import random, datetime
import requests, hashlib
import json
from django.shortcuts import render, redirect, reverse
from django.http import JsonResponse, HttpResponse
from django.views.generic import View
from django.db.models import Q
from django.conf import settings
from django.core.paginator import Paginator  # 分页器
from django.utils import timezone
# Create your views here.
from apps.wx_offical_account import models
from apps.spider_account.models import WechatUserModel
from apps.article.models import ArticleModel, ArticleImgsModel, ArticleContentModel
from utils.loginMixin.mixin import LoginRequiredMixin
# 自己写的工具类
from utils.searchOrg.searchs import search_org, get_artile_list
from utils.tools.myTools import md5, unix_to_time, time_to_unix, upload_to_oss
import oss2


# wx/official/offical_list/类型名/page页?sort=
# 默认类型名=default/page=1/sort=desc
class WXOfficlaShow(View):
    def get(self, request, type_name, page):
        # 从数据库获取所有公众号类型
        type_list = models.WxOfficalAccount.objects.filter(is_delete=0).values_list("article_type",
                                                                                    flat=True).distinct()

        if type_name == "default":
            wechat_list = models.WxOfficalAccount.objects.filter(is_delete=0, fake_id__isnull=False).order_by('id')
        elif type_name == 'available':
            wechat_list = models.WxOfficalAccount.objects.filter(is_delete=0, fake_id__isnull=False, state=0).order_by(
                'id')
        elif not models.WxOfficalAccount.objects.filter(article_type=type_name).exists():
            wechat_list = models.WxOfficalAccount.objects.filter(is_delete=0).order_by('id')
        else:
            wechat_list = models.WxOfficalAccount.objects.filter(Q(is_delete=0) & Q(article_type=type_name)).order_by(
                'id')

        paginator = Paginator(wechat_list, 10)
        # 获取第page页的内容
        max_page = 0
        if isinstance(paginator.count / 10, int):
            max_page = paginator.count // 10
        else:
            max_page = paginator.count // 10 + 1
        try:
            page = int(page)
        except Exception as e:
            page = 1
        if page > paginator.num_pages:
            page = 1
        # 获取第page页的Page实例对象
        skus_page = paginator.page(page)
        num_pages = int(paginator.num_pages)
        if num_pages < 5:
            pages = range(1, num_pages + 1)
        elif page <= 3:
            pages = range(1, 6)
        elif num_pages - page <= 2:
            pages = range(num_pages - 4, num_pages + 1)
        else:
            pages = range(page - 2, page + 3)
        return render(request, 'offical_list.html',
                      {'skus_page': skus_page, "type_name": type_name, 'pages': pages, "type_list": type_list,
                       "max_page": max_page})  # {'skus_page':skus_page,'pages':pages,"type_name":type_name})


class SearchOrg(LoginRequiredMixin, View):
    def post(self, request):
        # 从数据库获取token和cookies
        if not WechatUserModel.objects.filter(~Q(token='null')).exists():
            return JsonResponse({"status": False, "message": "cookie池数据为空，请先去采集号管理页对账号进行登录"})
        users = WechatUserModel.objects.filter(~Q(token='null'))
        cookies = random.choice(users)
        print(cookies.token)
        print(eval(cookies.cookies).get("Cookie"))
        data = None
        print(request.POST)
        # return JsonResponse({"status": True, "data": {'base_resp': {'ret': 0, 'err_msg': 'ok'}, 'list': [{'fakeid': 'MjM5ODUxMjExMA==', 'nickname': '财经早餐', 'alias': 'Femorning', 'round_head_img': 'http://mmbiz.qpic.cn/mmbiz_png/6GX0AKhZ258ibAAT8ESWm7JN62oh0jjfWfbAtibqhW0s7dGOPcEfXlNtUk0lZXNqpZ88997pXe5h3XSyDIvTBW5A/0?wx_fmt=png', 'service_type': 1}, {'fakeid': 'Mzg4NzI5MTA5NQ==', 'nickname': '财经早餐阅读', 'alias': '', 'round_head_img': 'http://mmbiz.qpic.cn/mmbiz_png/Wpa1YFIIC7kStlOWrzAyZLkvIQ0ESgmibp707HpEOdoeDfQ0kEgkYu7QsjrKn9jNsvdXd1IrULTciaJdGCho1x1A/0?wx_fmt=png', 'service_type': 2}, {'fakeid': 'MjM5MjkxNDQxMA==', 'nickname': '每日财经早餐', 'alias': 'cjing365', 'round_head_img': 'http://mmbiz.qpic.cn/mmbiz_png/vgWw4GhZDspZj8sMN5NuNz1FYVrmzx9yxtcUzLJkrrfIv2abGZjR3ZzibLTwicx9Fn5NxAX78Vddx8NXfkicovTDA/0?wx_fmt=png', 'service_type': 1}], 'total': 3}})
        response_data = search_org(org_name=request.POST.get("officialAccount", None),
                                   useragent=request.META.get("HTTP_USER_AGENT"), token=cookies.token,
                                   cookies_str=eval(cookies.cookies).get("Cookie"))
        print(response_data)
        if response_data.get("base_resp", None).get("err_msg", None) != "ok":
            # 删除该token
            users = WechatUserModel.objects.get(token=cookies.token)
            users.token = 'null'
            users.cookies = "null"
            users.save()
            print(response_data)
            return JsonResponse({"status": False, "message": "请求数据失败"})
        else:
            return JsonResponse({"status": True, "data": response_data})


class OnlineAddOrgView(LoginRequiredMixin, View):
    def post(self, request):
        print(request.POST)
        # 接收前端传过来的数据 并且上传图片到oss
        org_log = request.POST.get("org_logo_img", None)
        org_name = request.POST.get("org_name", None)
        alias = request.POST.get("alias", None)
        fake_id = request.POST.get("fake_id", None)

        # 查看数据是否在数据库中存在
        org_exists = models.WxOfficalAccount.objects.filter(org_name=org_name).exists()
        if org_exists:
            return JsonResponse({"status": False, "message": "该公众号数据库已经存在"})
        # 图片上传到OSS 然后返回对应的url
        logo_name = md5(org_log) + ".jpg"
        auth = oss2.Auth('LTAI4FjEyJMxz6WC6L3AbsUW', '1JJdHkbwTIkYgwqF0pJuoMigi5cGUH')
        bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', '51huoke')
        bucket.put_object("image/wx_official_logo/" + logo_name,
                          requests.get(org_log, headers={"user-agent": request.META.get("HTTP_USER_AGENT")}))
        logo_oss_name = "https://51huoke.oss-cn-shenzhen.aliyuncs.com/image/wx_official_logo/" + logo_name

        # 添加到数据库
        orgs = models.WxOfficalAccount.objects.create(
            fake_id=fake_id, wechat_code=alias, org_name=org_name, logo_url=logo_oss_name
        )
        orgs.save()
        return JsonResponse({"status": True})


# 在线搜索后添加公众号
class AddOrgView(LoginRequiredMixin, View):
    def post(self, request):
        print(request.POST)
        org_name = request.POST.get("orgName", None)
        fake_id = request.POST.get("fakeID", None)
        org_code = request.POST.get("orgId", None)
        org_link = request.POST.get("logoLink", None)
        use_for = request.POST.get("useFor", None)
        org_type = request.POST.get("orgType", None)
        org_desc = request.POST.get("orgDesc", None)
        org_level = request.POST.get("orgLevel", None)
        if not all([org_name, fake_id, use_for, org_type, org_level]):
            return JsonResponse({"status": False, "message": '数据填写不完整，*字段为必填项目'})
        if models.WxOfficalAccount.objects.filter(fake_id=fake_id).exists():
            return JsonResponse({"status": False, "message": '数据库已经存在'})
        # 图片上传到OSS 然后返回对应的url
        logo_name = md5(org_link) + ".jpg"
        auth = oss2.Auth('LTAI4FjEyJMxz6WC6L3AbsUW', '1JJdHkbwTIkYgwqF0pJuoMigi5cGUH')
        bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', '51huoke')
        bucket.put_object("image/wx_official_logo/" + logo_name,
                          requests.get(org_link, headers={"user-agent": request.META.get("HTTP_USER_AGENT")}))
        logo_oss_name = "https://51huoke.oss-cn-shenzhen.aliyuncs.com/image/wx_official_logo/" + logo_name
        orgs = models.WxOfficalAccount.objects.create(
            org_name=org_name, fake_id=fake_id, wechat_code=org_code, logo_url=logo_oss_name,
            user_for=self.format_userfor(use_for),
            article_type=org_type, org_desc=org_desc, spider_priority=self.format_level(org_level)
        )
        orgs.save()
        return JsonResponse({"status": True})

    def format_level(self, str):
        if "极高" == str.strip():
            return 4
        elif "高" == str.strip():
            return 3
        elif "中" == str.strip():
            return 2
        elif "低" == str.strip():
            return 1
        elif "极低" == str.strip():
            return 0
        else:
            return 0

    def format_userfor(self, str):
        if "官网" == str.strip():
            return 0
        if "51客" == str.strip():
            return 1
        else:
            return 2


# 删除公众号功能
class DeleteOrgView(LoginRequiredMixin, View):
    def get(self, request):
        print(request.GET)
        fake_id = request.GET.get("fake_id", None)
        if not fake_id:
            return JsonResponse({"status": False, "message": "删除失败，fakeid不存在"})
        orgs = models.WxOfficalAccount.objects.filter(fake_id=fake_id).first()
        orgs.is_delete = 1
        orgs.save()
        return JsonResponse({"status": True})


# 编辑公众号功能
class EditOrgView(View):
    def get(self, request, id):
        if not models.WxOfficalAccount.objects.filter(id=id).exists():
            return redirect(reverse("wx_official:offical_list", id, {"err_msg": "ID为：{} 的账号不存在".format(id)}))
        org = models.WxOfficalAccount.objects.filter(id=id).first()
        return render(request, 'edit_org.html', {"org": org, "last_path": request.path_info})

    def post(self, request, id):
        if not models.WxOfficalAccount.objects.filter(id=id).exists():
            return redirect(reverse("wx_official:offical_list", id, {"err_msg": "ID为：{} 的账号不存在".format(id)}))
        orgs = models.WxOfficalAccount.objects.get(id=id)
        org_name = request.POST.get("web_site_title", None)
        fakeID = request.POST.get("fakeID", None)
        web_site_logo = request.POST.get("web_site_logo", None)
        orgType = request.POST.get("orgTyoe", None)
        web_site_description = request.POST.get("web_site_description", None)
        useFor = request.POST.get("useFor", None)
        orgLevel = request.POST.get("orgLevel", None)
        if not all([org_name, fakeID, orgType, useFor, orgLevel]):
            return redirect(reverse("wx_official:offical_list", args=[orgs.id]), {"err_msg": "数据填写不完整"})
        orgs.org_name = org_name
        orgs.fake_id = fakeID
        if web_site_logo is not None and "https://51huoke.oss-cn-shenzhen.aliyuncs.com/image/wx_official_logo/" not in web_site_logo:  # 如果图片未上传且不为空
            # 长传图片到oss
            logo_name = md5(web_site_logo) + ".jpg"
            auth = oss2.Auth('LTAI4FjEyJMxz6WC6L3AbsUW', '1JJdHkbwTIkYgwqF0pJuoMigi5cGUH')
            bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', '51huoke')
            bucket.put_object("image/wx_official_logo/" + logo_name,
                              requests.get(web_site_logo, headers={"user-agent": request.META.get("HTTP_USER_AGENT")}))
            logo_oss_name = "https://51huoke.oss-cn-shenzhen.aliyuncs.com/image/wx_official_logo/" + logo_name
            orgs.logo_url = logo_oss_name
        orgs.article_type = orgType
        if web_site_description:
            orgs.org_desc = web_site_description
        orgs.spider_level = self.format_level(orgLevel)
        orgs.user_for = self.format_userfor(useFor)
        orgs.save()
        return redirect(reverse('wx_official:edit_org', args=[orgs.id]), {"org": orgs, "err_msg": "信息修改成功"})

    def format_level(self, str):
        if "极高" == str.strip():
            return 4
        elif "高" == str.strip():
            return 3
        elif "中" == str.strip():
            return 2
        elif "低" == str.strip():
            return 1
        elif "极低" == str.strip():
            return 0
        else:
            return 0

    def format_userfor(self, str):
        if "官网" == str.strip():
            return 0
        if "51客" == str.strip():
            return 1
        else:
            return 2


# 显示公众号的文章列表页
class ArticleOrgView(View):
    def get(self, request, id, page):
        if not models.WxOfficalAccount.objects.filter(id=id).exists():
            return redirect(reverse("wx_official:offical_list"))
        org = models.WxOfficalAccount.objects.filter(id=id).first()
        sort_by = request.GET.get("sort", None)
        include = request.GET.get("include", None)
        if sort_by == "asc":
            articles = ArticleModel.objects.filter(org_id=org).order_by('article_update_on')  # 文章列表 按照发布时间降序排序
        elif include == 'is_spider':
            articles = ArticleModel.objects.filter(org_id=org, spidered=1).order_by(
                '-article_update_on')  # 文章列表 按照发布时间降序排序
        elif include == 'no_spider':
            articles = ArticleModel.objects.filter(org_id=org, spidered=0).order_by(
                '-article_update_on')  # 文章列表 按照发布时间降序排序
        else:
            articles = ArticleModel.objects.filter(org_id=org).order_by('-article_update_on')  # 没有区分条件 就默认用时间倒叙
        paginator = Paginator(articles, 10)
        # 获取第page页的内容
        try:
            page = int(page)
        except Exception as e:
            page = 1
        if page > paginator.num_pages:
            page = 1
        # 获取第page页的Page实例对象
        skus_page = paginator.page(page)
        num_pages = int(paginator.num_pages)
        if num_pages < 5:
            pages = range(1, num_pages + 1)
        elif page <= 3:
            pages = range(1, 6)
        elif num_pages - page <= 2:
            pages = range(num_pages - 4, num_pages + 1)
        else:
            pages = range(page - 2, page + 3)
        for i in skus_page:
            print(i.title)
        return render(request, "org_article.html",
                      {"org": org, "articles": articles, 'skus_page': skus_page, 'pages': pages, "sort": sort_by,
                       "include": include})


class setOrgsDisabledView(View):
    '''设置公众号无法抓取的状态'''

    def post(self, request):
        print(request.POST)
        if not models.WxOfficalAccount.objects.filter(fake_id=request.POST.get("fakeid", None)).exists():
            return JsonResponse({"status": False, "message": "机构不存在"})
        orgs = models.WxOfficalAccount.objects.filter(fake_id=request.POST.get("fakeid", None)).first()
        orgs.state = 1
        orgs.save()
        return JsonResponse({"status": True})


class SetAvailiableView(View):
    """设置公众号解禁"""

    def post(self, request):
        print(request.POST)
        if not models.WxOfficalAccount.objects.filter(fake_id=request.POST.get("fakeid", None)).exists():
            return JsonResponse({"status": False, "message": "机构不存在"})
        orgs = models.WxOfficalAccount.objects.filter(fake_id=request.POST.get("fakeid", None)).first()
        orgs.state = 0
        orgs.save()
        return JsonResponse({"status": True})


class SpiderOrgView(View):
    """爬取公众号列表页"""

    def post(self, request):
        # 1. 判断账号是否存在
        org = models.WxOfficalAccount.objects.filter(fake_id=request.POST.get("fakeId", None)).exists()
        if not org:
            return JsonResponse({"status": False, "message": "该公众号不存在", "errCode": 1})

        # 2. 判断最近有没有爬过该公众号的数据
        orgs = models.WxOfficalAccount.objects.filter(fake_id=request.POST.get("fakeId", None)).first()
        spider_interval = (timezone.now() - orgs.spider_time).seconds
        if spider_interval < 36000:
            return JsonResponse({"status": False, "message": "10小时之内有抓取过该账号，抓取太频繁了", "errCode": 2})

        # 3. 下一步从数据库中读取cookies 抓取数据
        cookies_list = WechatUserModel.objects.filter(~Q(token='null'))  # 从数据获取cookie和token 列表
        if len(cookies_list) < 1:
            return JsonResponse({"status": False, "message": "数据库cookie池为空 请先去采集号登陆cookies", "errCode": 3})
        while True:
            cookies = random.choice(cookies_list)
            orgs = models.WxOfficalAccount.objects.filter(fake_id=request.POST.get("fakeId", None)).first()
            # 循环从数据库获取cookies
            response_data = get_artile_list(fakeid=request.POST.get("fakeId", None),
                                            useragent=request.META.get("HTTP_USER_AGENT"), token=cookies.token,
                                            cookies_str=eval(cookies.cookies).get("Cookie"))
            print(response_data)
            print(eval(cookies.cookies).get("Cookie"))
            if response_data.get("base_resp", None).get("err_msg", None) != "ok":
                # 删除该token
                users = WechatUserModel.objects.get(token=cookies.token)
                users.token = 'null'
                users.cookies = "null"
                users.save()
                print(response_data)
                continue  # 抓取失败就继续循环
            else:
                # 爬取成功后要修改spider_time字段
                orgs.spider_time = timezone.now()
                orgs.save()  # 保存
                print("修改抓取时间为", timezone.now())
                self.format_response_data(orgs, request.META.get("HTTP_USER_AGENT"), **response_data)
                return JsonResponse({"status": True, "data": response_data, 'message': "抓取成功", "errCode": 0})

    def format_response_data(self, orgs, useragent, **data):
        """专门处理微信公众号文章列表页的数据"""
        print("进入函数")
        for index in data['app_msg_list']:
            author_name = index.get("author_name", None)
            link = index.get("link", None)
            md5_link = md5(link)
            digest = index.get("digest", None)
            title = index.get("title", None)
            update_time = index.get("update_time", None)
            create_time = index.get("create_time", None)
            cover = index.get("cover", None)
            print(update_time, create_time)
            # 如果文章存在 就不在插入数据库
            if ArticleModel.objects.filter(article_link=link.strip()).exists():
                print("文章已经存在")
                continue  # 跳出当前循环 进入下一轮循环
            if update_time:
                article_create = unix_to_time(int(update_time))
            else:
                article_create = timezone.now()
            if create_time:
                article_update = unix_to_time(int(create_time))
            else:
                article_update = timezone.now()

            # 保存文章数据
            article = ArticleModel.objects.create(
                article_author=author_name,
                article_link=link,
                article_desc=digest,
                title=title,
                org_id=orgs,
                article_create_on=article_create,
                article_update_on=article_update,
                md5_link=md5_link,
                cover_img_link=cover if cover else "default:" + str(timezone.now()),
                md5_cover_link=md5(cover),
                org_name=orgs.org_name
            )
            # 处理缩略图  上传到OSS
            if cover:
                new_link = upload_to_oss(cover, useragent)
                if not new_link:  # 上传不成功
                    img_obj = ArticleImgsModel.objects.create(
                        article=article,
                        img_oss_name=new_link,
                        img_oss_url=new_link,
                        img_wechat_url=cover,
                        update_state=2,
                        is_covers=1
                    )
                    img_obj.save()
                else:
                    img_obj = ArticleImgsModel.objects.create(
                        article=article,
                        img_oss_name=new_link,
                        img_oss_url=new_link,
                        img_wechat_url=cover,
                        update_state=1,
                        is_covers=1
                    )
                    img_obj.save()
            article.save()
